Add verify-codelock CLI for CI and pre-commit hooks#35
Draft
taneliang wants to merge 1 commit into
Draft
Conversation
Adds an `npx`-runnable `verify-codelock` binary that walks a set of eslint-/prettier-style glob patterns and confirms that every tscodegen-generated file matched by the globs still has a valid codelock hash. Files that are not tscodegen-generated are silently skipped, so the CLI can safely be pointed at broad globs (e.g. `**/*`) without an allowlist. This supersedes the previously planned ESLint rule: since tscodegen now supports non-TypeScript generated files (e.g. `.gitattributes` via the `CommentSyntax` option), an ESLint rule can't cover every case. A standalone CLI can. Highlights: * `detectCommentSyntax` helper inspects a file's first docblock and returns the `CommentSyntax` tscodegen used to lock it — or `undefined` if the file isn't a tscodegen codelock. * `src/cli/verifyCodelock.ts` implements argument parsing, glob resolution (via `tinyglobby`), per-file verification, colored output (via `picocolors`), and exit-code handling (0 ok, 1 tampered/error, 2 invalid invocation). * `bin/verify-codelock.js` is the shebang wrapper registered in `package.json`'s `bin` field. * Package now explicitly ships `dist/`, `bin/`, `CHANGELOG.md`, `LICENSE`, and `README.md` via a `files` allowlist. * New module-level exports from the package root: `codelock` and `detectCommentSyntax`, so consumers can build their own verification tooling on top of the same primitives. * 31 new unit tests (CLI + detector) covering ok/tampered/skipped/error classification, glob expansion, literal-path and directory arguments, ignore patterns, quiet/verbose modes, help/version output, and argument-parsing edge cases. Co-authored-by: E-Liang Tan <taneliang@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds an
npx-runnableverify-codelockbinary that walks a set of eslint-/prettier-style glob patterns and confirms that every tscodegen-generated file matched by the globs still has a valid codelock hash. Files that are not tscodegen-generated (i.e. don't contain an@generated Codelock<<…>>or@generated-editable Codelock<<…>>marker) are silently skipped, so the CLI can safely be pointed at broad globs like**/*without having to maintain an allowlist.This replaces the previously planned ESLint rule: since tscodegen now supports non-TypeScript generated files (e.g.
.gitattributesvia theCommentSyntaxoption), an ESLint rule can't cover every case. A standalone CLI can.Usage
Exit codes:
0— all matched tscodegen-generated files have valid codelocks.1— one or more files were tampered with, matched no files, or could not be read.2— invalid invocation (missing patterns, unknown option).Implementation notes
detectCommentSyntaxhelper (src/detectCommentSyntax.ts) inspects a file's first docblock and returns theCommentSyntaxtscodegen used to lock it (orundefinedif the file isn't a tscodegen codelock). Both/** … */JSDoc docblocks and arbitrary line-comment prefixes (#,//, etc.) are supported. The detector round-trips throughgetCodelockInfoso lookalike lines (e.g. a// @generated Codelock<<foo>>comment sitting in the middle of a source file) are not mistakenly classified as generated files.src/cli/verifyCodelock.tscontains a small hand-rolled arg parser (to avoid pulling in a yargs-sized dependency), glob resolution viatinyglobby, per-file verification, colored output viapicocolors, and an explicitrun/mainsplit so the CLI can be driven directly from tests.bin/verify-codelock.jsis a thin shebang wrapper thatrequires the compiled entry fromdist/cli/verifyCodelock.jsand forwards the exit code. Wired up viapackage.json's"bin"field, which is whatnpxkeys off of."files"allowlist (dist,bin,CHANGELOG.md,LICENSE,README.md) so shipped tarballs stay minimal. Verified withnpm packthat thebinscript anddist/cli/*files are included.bin/**is added to the ignore list so the intentionally CommonJS-style wrapper doesn't trip@typescript-eslint/no-require-imports.codelockanddetectCommentSyntaxare re-exported fromsrc/index.tsso consumers can build their own verification tooling on the same primitives.Dependencies
Two new runtime dependencies, both already in the dep tree transitively (so
yarn.lockis unchanged):tinyglobby@^0.2.16— tiny (≈60 KB) fast-glob-compatible matcher, good fit for eslint-/prettier-style patterns.picocolors@^1.1.1— tiny (≈28 KB) terminal color library with a TTY-aware default.Tests
31 new unit tests across
src/detectCommentSyntax.test.tsandsrc/cli/verifyCodelock.test.ts, covering:--ignorepatterns (multiple,=-form and space-form).--verbose/--quietmodes.--help,--version, unknown-option, missing-pattern, and--arg-parsing edge cases.main()run against a fixture directory containing editable TS, line-comment.gitattributes, plain source files, and tampered generated output.Full suite: 125 tests passing (was 94). Lint, typecheck, and build all clean.
Manual verification
Packed the module with
npm pack, installed the tarball into a fresh scratch project, and rannpx verify-codelock '**/*'against a tree containing a mix of editable TS, a locked.gitattributes, a plain.tsfile, and a tampered generated file. The CLI correctly classified each file, summarised results, and exited1only when a tampered file was present.Docs
CommentSyntaxfeature.